package Api.WxPay.Payment;

import Util.HttpUtil;
import com.alibaba.fastjson.JSON;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static Util.Tools.MaptoStr;
import static Util.Tools.getMD5;
import static org.apache.http.util.TextUtils.isEmpty;

/**
 * 微信公众号支付
 */
public class WxGzhPay {
    public static void main(String[] args) {
        try {
            // 目标URL
            String url = "https://pay.heepay.com/Payment/Index.aspx";
            //需要的MD5密钥，商户后台网关密钥下面第一个
            String key = "651886F030134F848F548A12";
            //商户编号，（汇付宝商户内码：七位整数数字）
            String agent_id = "1664502";
            //子商户号
            String ref_agent_id = "";
            // 获取当前14位时间戳
            Date now = new Date();
            // 创建 SimpleDateFormat 对象，指定日期格式
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            String timestamp = dateFormat.format(now);

            String is_phone = "1";
            String is_frame = "1";


            //固定版本号
            String version = "1";
            String pay_type = "30";
            String agent_bill_id = timestamp;
            String agent_bill_time = timestamp;
            String pay_amt = "0.01";
            /*
            支付后的异步地址，URL参数是以http://或https://开头的完整URL地址(后台处理)，提交的url地址必须外网能访问到，否则无法通知商户。值可以为空，但不可以为null。
             */
            String notify_url = "";

            String return_url = "https://www.baidu.com";


/*            String ch = "课程预定";
            String payTitle= URLEncoder.encode(ch, "UTF-8");
            String reurl = "http://www.yysdraw.com/user/login?isReturn=1&payTitle=" +
                    payTitle+"&payPrice=0.01&PayId=1726840432669593602&skmbh=SKM20230719092811698844&payOrder=1176519959166058496";

            String return_url1= URLEncoder.encode(reurl, "UTF-8");*/


            //	用户所在客户端的真实ip其中的"."替换为"_" 。因为近期我方发现用户在提交数据时，user_ip在网络层被篡改，导致签名错误，所以我们规定使用这种格式。
            String user_ip = "127_127_12_12";
            //产品数量（不参加签名）
            String goods_num = "1";
            //商品名称，不能为空（不参加签名）
            String goods_name = "商品名称";
            String goods_name1 = URLEncoder.encode(goods_name, "GBK");
            //	商户自定义，原样返回,可以为空。（不参加签名）
            String remark = "商户自定义,原样返回,可以为空";
            String remark1 = URLEncoder.encode(remark, "GBK");
            //支付说明，（不参加签名）
            String goods_note = "支付说明,比如购买商品";
            String goods_note1 = URLEncoder.encode(goods_note, "GBK");
            //签名类型
            String sign_type = "MD5";


            Map<String, String> map = new HashMap<String, String>();
            map.put("s", "WAP");
            map.put("n", "网站名称");
            map.put("id", "http://www.baidu.com/");

            /* 如果需要返回JSAPI参数自行拉起支付  meta_option则加入{"wx_openid":"用户openid","wx_sub_appid":"公众号appid"}；接入之前先对接群内联系汇元运营配置公众号appid；
            *  微信调起jsapi官网文档：https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
            map.put("wx_openid", "");
            map.put("wx_sub_appid", "");*/

            //代表分润单
            //map.put("is_guarantee", "1");
            String a = JSON.toJSONString(map);
            // Step 1: 将JSON串编码为GBK格式的字节数组
            byte[] gbkBytes;
            try {
                gbkBytes = a.getBytes("GBk");
            } catch (UnsupportedEncodingException e) {
                System.out.println("不支持的字符集：" + e.getMessage());
                return;
            }
            // Step 2: 对GBK格式的字节数组进行Base64编码
            String base64EncodedString = Base64.getEncoder().encodeToString(gbkBytes);
            String meta_option = URLEncoder.encode(base64EncodedString);


            // 请求参数，以Map形式表示
            Map<String, String> parameters = new HashMap<String, String>();

            if (isEmpty(ref_agent_id)) {
                //拼接待加密参数
                StringBuilder builder = new StringBuilder();
                builder.append("version=");
                builder.append(version);
                builder.append("&agent_id=");
                builder.append(agent_id);
                builder.append("&agent_bill_id=");
                builder.append(agent_bill_id);
                builder.append("&agent_bill_time=");
                builder.append(agent_bill_time);
                builder.append("&pay_type=");
                builder.append(pay_type);
                builder.append("&pay_amt=");
                builder.append(pay_amt);
                builder.append("&notify_url=");
                builder.append(notify_url);
                builder.append("&return_url=");
                builder.append(return_url);
                builder.append("&user_ip=");
                builder.append(user_ip);
                builder.append("&key=");
                builder.append(key);

                String Date = builder.toString();
                //MD5加密得出签名结果
                String sign = getMD5(Date);

                parameters.put("version", version);
                parameters.put("pay_type", pay_type);
                parameters.put("is_phone", is_phone);
                parameters.put("is_frame", is_frame);
                parameters.put("agent_id", agent_id);
                parameters.put("agent_bill_id", agent_bill_id);
                parameters.put("agent_bill_time", agent_bill_time);
                parameters.put("pay_amt", pay_amt);
                parameters.put("notify_url", notify_url);
                parameters.put("return_url", return_url);
                parameters.put("user_ip", user_ip);
                parameters.put("goods_name", goods_name1);
                parameters.put("goods_num", goods_num);
                parameters.put("remark", remark1);
                parameters.put("goods_note", goods_note1);
                parameters.put("meta_option", meta_option);
                parameters.put("sign_type", sign_type);
                parameters.put("sign", sign);

            } else {
                //拼接待加密参数
                StringBuilder builder = new StringBuilder();
                builder.append("version=");
                builder.append(version);
                builder.append("&agent_id=");
                builder.append(agent_id);
                builder.append("&agent_bill_id=");
                builder.append(agent_bill_id);
                builder.append("&agent_bill_time=");
                builder.append(agent_bill_time);
                builder.append("&pay_type=");
                builder.append(pay_type);
                builder.append("&pay_amt=");
                builder.append(pay_amt);
                builder.append("&notify_url=");
                builder.append(notify_url);
                builder.append("&return_url=");
                builder.append(return_url);
                builder.append("&user_ip=");
                builder.append(user_ip);
                builder.append("&key=");
                builder.append(key);
                builder.append("&ref_agent_id=");
                builder.append(ref_agent_id);

                String Date = builder.toString();
                //MD5加密得出签名结果
                String sign = getMD5(Date);

                parameters.put("version", version);
                parameters.put("pay_type", pay_type);
                parameters.put("is_phone", is_phone);
                parameters.put("is_frame", is_frame);
                parameters.put("agent_id", agent_id);
                parameters.put("ref_agent_id", ref_agent_id);
                parameters.put("agent_bill_id", agent_bill_id);
                parameters.put("agent_bill_time", agent_bill_time);
                parameters.put("pay_amt", pay_amt);
                parameters.put("notify_url", notify_url);
                parameters.put("return_url", return_url);
                parameters.put("user_ip", user_ip);
                parameters.put("goods_name", goods_name1);
                parameters.put("goods_num", goods_num);
                parameters.put("remark", remark1);
                parameters.put("goods_note", goods_note1);
                parameters.put("meta_option", meta_option);
                parameters.put("sign_type", sign_type);
                parameters.put("sign", sign);
            }

            //打印请求参数
            String Str = MaptoStr(parameters);
            System.out.println("发送请求数据：-------------------------------->"+ Str);
            //注意 微信公众号支付使用时（非jsapi） 组装好参数，微信内环境前端去请求

            String Result = HttpUtil.sendPost1(url,parameters);
            System.out.println("返回响应数据：-------------------------------->"+Result);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
